﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using AutoIt_IDE;
using System.Text.RegularExpressions;
using System.Xml.Serialization;

namespace AutoIt_Elements.Core.LanguageManager
{
    class LanguageManager
    {
        private Dictionary<string, Language> loadedLangs = new Dictionary<string, Language>();
        private Language currentLang = null;

        public LanguageManager()
        {
            // Load all Languages
            String[] files = Directory.GetFiles(Environment.CurrentDirectory + @"\Lang");
            foreach (String file in files)
            {
                Program.WriteDebugLine(file);

                Language lang = XMLLoadLanguage(file);

                if (lang != null)
                    loadedLangs.Add(lang.Name, lang);
            }
        }

        /// <summary>
        /// Gets or sets the current language
        /// </summary>
        public Language CurrentLanguage
        {
            get
            {
                return this.currentLang;
            }
            set
            {
                this.currentLang = value;
            }
        }

        public Dictionary<string,Language> LoadedLanguages
        {
            get
            {
                return this.loadedLangs;
            }
        }

        public static Language XMLLoadLanguage(string file)
        {
            if (File.Exists(file))
            {
                try
                {
                    Language lang = new Language();
                    Dictionary<string, string> tokens = new Dictionary<string, string>();

                    XPathDocument doc = new XPathDocument(file);
                    XPathNavigator nav = doc.CreateNavigator();

                    XPathExpression expr = nav.Compile("/language");
                    XPathNodeIterator it = nav.Select(expr);
                            
                    it.MoveNext();
                    lang.Name = it.Current.GetAttribute("name", "");

                    XPathNavigator nav2 = it.Current.Clone();
                    XPathNodeIterator it2 = nav2.SelectChildren(XPathNodeType.Element);

                    do
                    {
                        XPathNavigator nav3 = it2.Current.Clone();

                        try
                        {
                            if (nav3.Name == "token")
                                tokens.Add(nav3.GetAttribute("name", ""), nav3.Value);
                        }
                        catch (ArgumentException)
                        {
                            lang.IsCorrupted = true;
                            continue;
                        }
                    } while (it2.MoveNext());

                    lang.Tokens = tokens;

                    return lang;
                }
                catch (XmlException ex)
                {
                    Program.WriteDebugLine(ex.Message);
                    return null;
                }
            }
            else
            {
                Program.WriteDebugLine("Lang File not found!");
                return null;
            }
        }

        public Language LoadLanguage(String path)
        {
            if (File.Exists(path))
            {
                XmlReader reader = XmlReader.Create(path);
                XmlSerializer ser = new XmlSerializer(typeof(Language));

                if (ser.CanDeserialize(reader))
                {
                    object data = ser.Deserialize(reader);
                    reader.Close();
                    if (data is Language)
                    {
                        Language lang = (Language)data;
                        return lang;
                    }
                    else
                    {
                        throw new XmlException("Can't read Language File: " + path);
                    }
                }
                else
                {
                    throw new XmlException("Can't read Language File: " + path);
                }
            }
            else
            {
                throw new FileNotFoundException("Could not find Language File: " + path, path.Split('\\')[path.Split('\\').Length - 1]);
            }
        }

        public void SaveLanguage(Language lang, String destination)
        {
            if (!lang.IsCorrupted)
            {
                XmlWriter writer = XmlWriter.Create(destination);
                XmlSerializer ser = new XmlSerializer(typeof(Language));

                ser.Serialize(writer, lang);
                writer.Close();
            }
            else
            {
                // TODO :: Create "InvalidLanguageException"
                throw new Exception("Language File is corrupted!");
            }
        }

        public string getTokenValue(string token)
        {
            if (this.currentLang != null)
            {
                if (this.currentLang.Tokens.ContainsKey(token))
                    return this.currentLang.Tokens[token];
                else
                {
                    Program.WriteDebugLine("Token " + token + " not found!");
                    return String.Empty;
                }
            }
            else
            {
                Program.WriteDebugLine("No Language loaded.");
                return String.Empty;
            }
        }
    }
}
